// -*- mode: c++; coding: utf-8 -*-

#include <Ice/Identity.ice>
#include <Ice/BuiltinSequences.ice>

module Robots {

  interface Agent;
  sequence<Agent*> AgentSeq;

  interface Robot;
  sequence<Robot*> RobotSeq;

  interface AgentTeam {
    // TODO: change for RobotSeq.
    AgentSeq create (Ice::StringSeq robots);
    idempotent AgentSeq list ();
  };

  interface RobotFactory {
    RobotSeq create (Ice::StringSeq addresses);
    idempotent RobotSeq list ();
  };  

  enum Role {Leader, Explorer};

  struct Vec2 {
    int x;
    int y;
  };

  struct SignPost {
    Vec2 pos;
  };

  sequence<SignPost> SignPostSeq;

  struct Bid {
    Agent* ag;
    SignPost sp;
    int value;
  };

  interface Auctioneer {
    ["ami"] void begin ();
    ["ami"] void receiveBid (Bid b);
    Agent* getLeader (SignPost sp);
  };

  class Message {};

  class Announcement extends Message {
    SignPostSeq signposts;
  };

  class Close extends Message {
    SignPost sp;
  };

  class Finish extends Message {};

  interface Agent {
    ["ami"] void inform (Message m);
    void destroy ();
  };

  exception AlreadySubscribed {};

  struct RobotPos {
    Vec2 pos;
    float dir;
  };

  interface Camera {
    idempotent RobotPos getRobotPos (Ice::Identity robot);
    void subscribe (Agent* a) throws AlreadySubscribed;
    void unsubscribe (Agent* a);
  };

  enum Speed {SLow, SMedium, SHigh};
  enum Resolution {RLow, RMedium, RHigh};

  enum Movement {Forward, Backward, Left, Right};
  enum Direction {DLeft, DRight};

  interface Robot {
    void move (RobotPos to);
    void stop ();
    void turn (Direction dir,
	       int degrees);
    Ice::ByteSeq capture (Resolution res);
    void setLaser (bool on);
    void destroy ();
  };
  
};
